package com.hejjon.knowledgebase.config;

import com.alibaba.fastjson.JSON;
import com.hejjon.knowledgebase.annotation.IgnoreWrapper;
import com.hejjon.knowledgebase.annotation.RestWrapper;
import com.hejjon.knowledgebase.bean.ResponseResult;
import com.hejjon.knowledgebase.constant.StandardContentType;
import com.hejjon.knowledgebase.util.ServletsUtil;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

import static com.alibaba.fastjson.serializer.SerializerFeature.WriteMapNullValue;


/**
 *  接口统一包装返回值配置类
 * @author:
 * @date: 2022-12-06 19:00:36
 * @since: 1.0
 */
@Configuration
public class WrapperResultConfig implements HandlerMethodReturnValueHandler {

    @Resource
    private RequestMappingHandlerAdapter requestMappingHandlerAdapter;

    /**
     *  程序加载完毕后将配置的实例添加到 RequestMappingHandlerAdapter
     */
    @PostConstruct
    public void compare() {
        List<HandlerMethodReturnValueHandler> handlers = requestMappingHandlerAdapter.getReturnValueHandlers();
        List<HandlerMethodReturnValueHandler> list = new ArrayList<>();
        list.add(this);
        // ！！！注意这里，需要将requestMappingHandlerAdapter 原有的返回值处理器添加进去
        if (handlers != null) {
            list.addAll(handlers);
        }
        requestMappingHandlerAdapter.setReturnValueHandlers(list);
    }


    @Override
    public boolean supportsReturnType(MethodParameter methodParameter) {
        // 类上没有@RestWrapper 注解，直接返回false，不对返回值进行包装
        if (!methodParameter.getContainingClass().isAnnotationPresent(RestWrapper.class)) {
            return false;
        }
        // 方法上加了 @IgnoreWrapper 注解表示忽略包装该方法, 返回false
        return !methodParameter.hasMethodAnnotation(IgnoreWrapper.class);
    }

    @Override
    public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest nativeWebRequest) throws Exception {
        HttpServletResponse response = nativeWebRequest.getNativeResponse(HttpServletResponse.class);
        if (null == response) {
            return;
        }
        ResponseResult<?> result;
        if (returnValue instanceof ResponseResult) {
            result = (ResponseResult<?>) returnValue;
        } else {
            result = ResponseResult.success().data(returnValue);
        }
        mavContainer.setRequestHandled(true);
        // 设置响应格式
        response.setContentType(StandardContentType.APPLICATION_JSON);
        ServletsUtil.transfer(response, JSON.toJSONString(result, WriteMapNullValue).getBytes());
    }
}
